package com.jmcgg.freesky.common.util;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

import org.apache.log4j.Logger;

/**
 * Title: FreeSky Common Java Library <br>
 * Description: FreeSky Common Java Library <br>
 * Copyright: Copyright (c) 2005~2009 www.afss.cn <br>
 * Company: Amei's FreeSky Studio <br>
 * 
 * @author <b>Jacky Chou</b> (AFSS [Amei's FreeSky Studio])
 * @version 1.2.1, 2008-08-05, Clean and optimize the source code.<br>
 *          1.2.0, 2008-02-23, Upgrade freesky.jar to 1.2.0 with Struts 2<br>
 *          1.0.0, 2006-05-30, Initial Version
 */
public class AlgorithmUtil extends FreeskyUtil {
	/**
	 * Logger for this class
	 */
	private static final Logger logger = Logger.getLogger(AlgorithmUtil.class);

	public static String base64Decode(String encoded) {
		byte[] bytes = null;
		try {
			bytes = encoded.getBytes("UTF-8");
		} catch (UnsupportedEncodingException ignored) {
		}
		Base64Decoder in = new Base64Decoder(new ByteArrayInputStream(bytes));
		ByteArrayOutputStream out = new ByteArrayOutputStream(
				(int) (bytes.length * 0.67));
		try {
			byte[] buf = new byte[4 * 1024]; // 4K buffer
			int bytesRead;
			while ((bytesRead = in.read(buf)) != -1) {
				out.write(buf, 0, bytesRead);
			}
			out.close();
			return new String(out.toByteArray(), "UTF-8");
		} catch (IOException ignored) {
			return null;
		}
	}

	public static String base64Encode(String unencoded) {
		byte[] bytes = null;
		try {
			bytes = unencoded.getBytes("UTF-8");
		} catch (UnsupportedEncodingException ignored) {
		}

		ByteArrayOutputStream out = new ByteArrayOutputStream(
				(int) (bytes.length * 1.37));
		Base64Encoder encodedOut = new Base64Encoder(out);

		try {
			encodedOut.write(bytes);
			encodedOut.close();
			return out.toString("UTF-8");
		} catch (IOException ignored) {
			return null;
		}
	}

	private static String bytes2Hex(byte[] bts) {
		String des = "";
		String tmp = null;
		for (int i = 0; i < bts.length; i++) {
			tmp = (Integer.toHexString(bts[i] & 0xFF));
			if (tmp.length() == 1) {
				des += "0";
			}
			des += tmp;
		}
		return des;
	}

	/**
	 * encode the strSrc to strDes with the encodeName algorithm
	 * 
	 * @param unencoded
	 *            is a string will be encrypted
	 * @param encodeName
	 *            is the algorithm name will be used. Default value is "MD5"
	 * @return String encoded string
	 */
	public static String encode(String unencoded, String encodeName) {
		if (unencoded == null)
			return null;
		MessageDigest md = null;
		String strDes = null;

		byte[] bt = unencoded.getBytes();
		try {
			if (encodeName == null || encodeName.equals("")) {
				encodeName = "MD5";
			}
			md = MessageDigest.getInstance(encodeName);
			md.update(bt);
			strDes = bytes2Hex(md.digest()); // to HexString
			return strDes;
		} catch (NoSuchAlgorithmException e) {
			logger.error("encode(String, String) - String strSrc=" + unencoded
					+ ", String encodeName=" + encodeName, e);
		}
		return null;
	}

	public static String encodeByMD5(String unencoded) {
		return encode(unencoded, "MD5");
	}

	public static String encodeBySHA1(String unencoded) {
		return encode(unencoded, "SHA-1");
	}

	public static String encodeBySHA256(String unencoded) {
		return encode(unencoded, "SHA-256");
	}

	public static void main(String[] args) {
		String unencoded = "可以加密汉字.Oh,and english";
		System.out.println("Source String:" + unencoded);
		System.out.println("Encrypted String:");
		System.out.println("Use Default:" + encode(unencoded, null));
		System.out.println("Use MD5  :" + encode(unencoded, "MD5"));
		System.out.println("Use SHA:" + encode(unencoded, "SHA-1"));
		System.out.println("Use SHA-256:" + encode(unencoded, "SHA-256"));
		// System.out.println("------------------------------------------------")
		// ;
		// System.out.println(encodeByMD5(""));
		// System.out.println("d41d8cd98f00b204e9800998ecf8427e");
		// System.out.println("------------------------------------------------")
		// ;
		// System.out.println("a");
		// System.out.println(encodeByMD5("a"));
		// System.out.println("0cc175b9c0f1b6a831c399e269772661");
		// System.out.println("------------------------------------------------")
		// ;
		// System.out.println("abc");
		// System.out.println(encodeByMD5("abc"));
		// System.out.println("900150983cd24fb0d6963f7d28e17f72");
		// System.out.println("------------------------------------------------")
		// ;
		// System.out.println("message digest");
		// System.out.println(encodeByMD5("message digest"));
		// System.out.println("f96b697d7cb7938d525a2f31aaf161d0");
		// System.out.println("------------------------------------------------")
		// ;
		// System.out.println("abcdefghijklmnopqrstuvwxyz");
		// System.out.println(encodeByMD5("abcdefghijklmnopqrstuvwxyz"));
		// System.out.println("c3fcd3d76192e4007dfb496cca67e13b");
		// System.out.println("------------------------------------------------")
		// ;
		// System.out
		// .println(
		// "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789");
		// System.out
		// .println(encodeByMD5(
		// "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"));
		// System.out.println("d174ab98d277d9f5a5611c2c9f419d9f");
		// System.out.println("------------------------------------------------")
		// ;
		// System.out
		// .println(
		// "12345678901234567890123456789012345678901234567890123456789012345678901234567890"
		// );
		// System.out
		// .println(encodeByMD5(
		// "12345678901234567890123456789012345678901234567890123456789012345678901234567890"
		// ));
		// System.out.println("57edf4a22be3c955ac49da2e2107b67a");

		System.out.println("------------------------------------------------");
		System.out.println(unencoded);
		String encode = base64Encode(unencoded);
		System.out.println(encode);
		System.out.println(base64Decode(encode));
		System.out.println("------------------------------------------------");
		System.out.println(unencoded);
		String encode1 = Base64Util.encode(unencoded);
		System.out.println(encode1);
		System.out.println(Base64Util.decode(encode1));

	}
}
